package com.houseman.workFlow.processer.impl;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.houseman.workFlow.WorkFlow;
import com.houseman.workFlow.WorkFlowBase;
import com.houseman.workFlow.bean.ApprovalInfo;
import com.houseman.workFlow.bean.TaskArea;
import com.houseman.workFlow.bean.WorkFlowBean;
import com.houseman.workFlow.dto.Approver;
import com.houseman.workFlow.dto.NextApprover;
import com.houseman.workFlow.dto.NextStepInfo;
import com.houseman.workFlow.processer.Processer;
import com.houseman.workFlow.service.ApproveService;
import com.houseman.workFlow.service.WorkFlowService;
import com.houseman.workFlow.service.impl.ApproveServiceImpl;
import com.houseman.workFlow.service.impl.WorkFlowServiceImpl;

/**
 * 流程处理核心对象
 */
public class WorkFlowProcesser extends Processer{

	//service
	WorkFlowService service = new WorkFlowServiceImpl();
	ApproveService appSer = new ApproveServiceImpl();
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public void proccess(HttpServletRequest request, HttpServletResponse response) {
		String workId = request.getParameter("workId");
		String action = request.getParameter("action");
		
		//session
		HttpSession session = request.getSession();
		
		try {
			String userId = (String) session.getAttribute("userId");
			String userName = (String) session.getAttribute("userName");
		
			/**1
			 * 获取当前流程信息
			 */
			WorkFlowBean bean = null;
			if(workId == null || "".equals(workId)) { //新建流程
				String graphId = request.getParameter("graphId");
				bean = service.queryNewBuildGraph(new Integer(graphId));
			}else {
				bean = service.queryWorkFlowInfo(new Integer(workId));
			}
			
			/**2
			 * 反射加载流程处理类
			 */
			Class clazz = Class.forName(bean.getProClass());
			Class sup = clazz.getSuperclass();
			WorkFlowBase base = (WorkFlowBase)clazz.newInstance();
			
			/**3
			 * 设置WorkFlowBase初始数据
			 */
			Field[] fs = sup.getDeclaredFields();
			Field.setAccessible(fs, true);//关闭权限访问
			for (int i = 0; i < fs.length; i++) {
				String name = fs[i].getName();
				if(name.equals("request")) {
					fs[i].set(base, request);
				}else if(name.equals("response")) {
					fs[i].set(base, response);
				}else if(name.equals("session")) {
					fs[i].set(base, session);
				}else if(name.equals("workId")) {
					fs[i].setInt(base, bean.getWorkId());
				}else if(name.equals("step")) {
					fs[i].setInt(base, bean.getStep());
				}else if(name.equals("name")) {
					fs[i].set(base, bean.getName());
				}else if(name.equals("creater")) {
					fs[i].set(base, bean.getCreater());
				}else if(name.equals("rollback")) {
					fs[i].setBoolean(base, bean.getRollback() == 1);
				}else if(name.equals("action")) {
					if("approval".equals(action)) {
						fs[i].set(base, "approval");
					}else if("submit".equals(action)) {
						fs[i].set(base, "submit");
					}
				}
			}
			
			/**4<core>
			 * 根据step定位处理方法
			 * 并执行该方法
			 */
			for(Method m: clazz.getDeclaredMethods()) {
				//获取标注中的step信息
				WorkFlow ann = m.getAnnotation(WorkFlow.class);
				//判断step
				if(ann != null && ann.step() == bean.getStep()) {
					m.setAccessible(true);//提高方法访问效率
					//反射执行方法
					m.invoke(base, new Object[] {});
					break;
				}
			}
			
			/**5
			 * 后续数据处理
			 */
			if("approval".equals(action)) {
				//下一办理审批人List
				Field f = sup.getDeclaredField("approver");
				f.setAccessible(true);
				List<NextApprover> approver = (List<NextApprover>)f.get(base);
				
				/**下一办理信息
				 * <同意>
				 */
				List<NextStepInfo> infos = service.queryNextStepInfo(bean.getGraphId(), bean.getStep());
				for (int i = 0; i < infos.size(); i++) {
					NextApprover info = new NextApprover();
					//根据line的审批人信息查找审批人
					List<Approver> apps = new ArrayList<Approver>();
					if(infos.get(i).getFlag() == 2) { //结束
						Approver app = new Approver();
						app.setUserId(userId);
						app.setUserName("关闭流程");
						infos.get(i).setRoleName("关闭");
						
						apps.add(app);
					}else {
						apps = service.queryApprovals(infos.get(i).getAppRole());
					}
					//注册审批人至审批集合
					info.setStep(infos.get(i).getStep());
					info.setName(infos.get(i).getRoleName());
					info.setApprovers(apps);
					approver.add(info);
				}
				
				/**回退审批人
				 * <不同意>
				 */
				if(workId != null && !"".equals(workId)) {
					ApprovalInfo nextApp = appSer.queryNewestByWorkId(new Integer(workId));
					request.setAttribute("nextApp", nextApp);
				}
				
				request.setAttribute("approver", approver);
				request.getRequestDispatcher("/WEB-INF/workFlow/page/approval.jsp").forward(request, response);
			}else if("submit".equals(action)) {
				//提交下一办理审批人以及审批信息
				String option = request.getParameter("hm_wf_option");
				String step = request.getParameter("hm_wf_step");
				String approvers = request.getParameter("hm_wf_apps");
				
				int thisStep = bean.getStep();
				int rollBack = "-1".equals(step)? 1 : 0;
				
				/**不同意时的回退操作
				 * 修改下一办理人和办理步骤
				 */
				if(rollBack == 1) {
					ApprovalInfo last = appSer.queryNewestByWorkId(new Integer(workId));
					step = String.valueOf(last.getStep()); //设置不同意时的上一办理step
					approvers = last.getApprover();
				}
				
				//1、更新该流程下一办理step和审批人
				bean.setStep(new Integer(step));
				bean.setApprover(approvers);
				if(bean.getWorkId() == 0) { //新建流程
					bean.setCreater(userId);
					workId = service.startWorkFlow(bean);
				}else {
					bean.setUpdater(userId);
					bean.setRollback(rollBack);
					service.updateNextStepInfo(bean);
				}
				
				//2、保存审批信息
				ApprovalInfo info = new ApprovalInfo();
				info.setWorkId(new Integer(workId));
				info.setStep(thisStep);
				info.setOpinion(option);
				info.setAgree(rollBack);
				info.setApprover(userId);
				info.setApproveName(userName);
				
				appSer.saveApproveInfo(info);
				
				//3、判断流程下一办理
				if(userId.equals(approvers)) { //当流程当前审批人是下一办理审批人时直接进入下一办理
					outInfo = nextMag(workId);
				}else {
					outInfo = closeWin;
				}
			}else { //页面
				TaskArea task = service.queryTaskAreaByStep(bean.getGraphId(), bean.getStep());
				if(task.getFlag() == 2) {
					outInfo = endWF(workId);
				}else {
					request.getRequestDispatcher(task.getPage()).forward(request, response);
				}
			}
			
		} catch (Exception e) {
			outInfo = errorInfo;
			e.printStackTrace();
		}
		
		/**
		 * 执行后返回信息
		 */
		if(!"".equals(outInfo)) {
			try {
				response.setContentType("text/html;charset=UTF-8");
				response.setCharacterEncoding("UTF-8");
				response.getWriter().write(outInfo);
				response.getWriter().flush();
				response.getWriter().close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
}
